﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace MiniChat
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static Color defaultcolor { set; get; }
        public static String hostip { set; get; }
        public static String UserName { set; get; }
        public static String PassWord { set; get; }
        public static Socket ConnectedSock { set; get; }
        public static bool Logged = false;
        public static bool noneclosesock = false;
        public static bool invokereturn = false;

        public static int buffersize = 1024;
        public MainWindow()
        {
           // hostip = "127.0.0.1";
            hostip = "112.213.87.154";
            defaultcolor = Colors.AliceBlue;
            InitializeComponent();
        }

        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }

        private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            txtUserName.Background = new SolidColorBrush(Colors.AliceBlue);
            txtPass.Background = new SolidColorBrush(Colors.AliceBlue);
             UserName = txtUserName.Text;
            if (UserName == "") { txtUserName.Background = new SolidColorBrush(Colors.Red);txtUserName.Focus() ;return; }
             PassWord = txtPass.Password;
             CGlobalVariable.UserName = UserName;            
            if (PassWord == "") { txtPass.Background = new SolidColorBrush(Colors.Red); txtPass.Focus();return; }
            pnLoading.Visibility = System.Windows.Visibility.Visible;
            Thread t = new Thread(new ThreadStart(Login));
            t.Start();
        }
        void Login()
        {
            txtNotice.Dispatcher.Invoke((Action)(() => { txtNotice.Text = "Begin connect to server ..."; }));
            Socket s = new Socket(AddressFamily.InterNetwork,
                                  SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse(hostip), 5203);
            try
            {
                s.Connect(ip);
            }catch{
                txtNotice.Dispatcher.Invoke((Action)(() => { txtNotice.Text = "Server down. Can't find login server ."; }));
            Thread.Sleep(2000);
            pnLoading.Dispatcher.Invoke((Action)(()=>{pnLoading.Visibility=System.Windows.Visibility.Hidden;}));
            return;
            }
            ConnectedSock = s;
            s.Send(Encoding.UTF8.GetBytes("login:" + UserName + ":" + PassWord));
            Thread listendata = new Thread(new ThreadStart(ListenData));
            listendata.Start();
        }

        void ListenData()
        {           
            Byte[] contextbytes = null;
            do
            {
                Byte[] bytes = new byte[buffersize];
              try
                {
                    if (invokereturn) { invokereturn = false;return; }
                    int i = ConnectedSock.Receive(bytes);
                    Array.Resize<Byte>(ref bytes, i);
                    if (i < buffersize)
                    {
                        String datatext = "";
                        if (contextbytes == null)
                        {
                            datatext = (Encoding.UTF8.GetString(bytes));
                            bytes = null;
                        }
                        else
                        {
                            datatext = (Encoding.UTF8.GetString(contextbytes));
                            contextbytes = null;
                        }
                        Ullity.Log(datatext,3);
                        var listcommand = Ullity.Split(datatext, "\n");
                        foreach (string strdata in listcommand)
                        {
                            Client.ProcessMessage(strdata, ConnectedSock, ref Logged);
                            if (strdata.Contains("loginstatus"))
                            {
                                if (Logged == false)
                                {
                                    txtNotice.Dispatcher.Invoke((Action)(() => {
                                        txtNotice.Text = "Invalid username or password";
                                    }));
                                    Thread.Sleep(2000);
                                    pnLoading.Dispatcher.Invoke((Action)(() =>
                                    {
                                        if (pnLoading.Visibility != System.Windows.Visibility.Hidden)
                                        {
                                            pnLoading.Visibility = System.Windows.Visibility.Hidden;
                                        }
                                    }));
                                }
                                else
                                {
                                    this.Dispatcher.Invoke((Action)(() => {                                     
                                    Chat frmChat = new Chat()
                                    {
                                        connectedsock = ConnectedSock
                                    };
                                    frmChat.Show();noneclosesock=true; this.Close();
                                    }));
                                    invokereturn = true ;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (contextbytes == null)
                        {
                            contextbytes = new byte[buffersize - 1];
                            bytes.CopyTo(contextbytes, 0);
                            bytes = null;
                        }
                        else
                        {
                            Array.Resize(ref contextbytes, contextbytes.Length + i);
                            bytes.CopyTo(contextbytes, contextbytes.Length - i);
                            bytes = null;
                        }

                    }
                    if (i == 0) { System.Threading.Thread.Sleep(100); }

                }
               catch (Exception ex)
               {
                    Console.WriteLine(ex.Message);
                    return;// close sock
               }

            } while (true);
        }

        void Connected()
        {

            MessageBox.Show("Ready");
        }
     
        private void txtPass_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter) { Button_Click(null, null); }
        }

        private void frmMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
          if(!noneclosesock)
              try
              {
                  ConnectedSock.Close();
              }
              catch {}
          noneclosesock = false;
        }

        private void txtUserName_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (File.Exists(System.IO.Path.Combine(CGlobalVariable.ImagePath, txtUserName.Text + ".jpg")))
            {
                BitmapImage bmi = new BitmapImage(new Uri(Path.Combine(CGlobalVariable.ImagePath, txtUserName.Text + ".jpg"), UriKind.Absolute));
                imgAvatar.Source = bmi;
            }
            else {
                BitmapImage bmi = new BitmapImage(new Uri(@"/Images/no_avatar.png", UriKind.Relative));
                imgAvatar.Source = bmi;
            }
        }
    }
}
